#include "AVDeMuxer.h"
#include<QDebug>
extern"C"
{
   #include<libavformat/avformat.h>
}

using AVPacketPtr = std::shared_ptr<AVPacket>;
using AVFramePtr = std::shared_ptr<AVFrame>;//别名

AVDeMuxer::AVDeMuxer()
    :quit_(false)
{
    pFormatCtx_ = avformat_alloc_context();

    pFormatCtx_->max_ts_probe= 50;
    pFormatCtx_->interrupt_callback.callback = InterruptFountion;
    pFormatCtx_->interrupt_callback.opaque = this;

    pFormatCtx_->flags |= AVFMT_FLAG_DISCARD_CORRUPT;
}

bool AVDeMuxer::Open(const QString path)
{
    //打开流地址
    //启动线程
    readThread_.reset(new std::thread([this,path](){
        this->FetchStream(path);
    }));
    return true;
}

void AVDeMuxer::Close()
{
    quit_= true;
    if(readThread_)
    {
        readThread_.reset();
        readThread_ = nullptr;
    }

    if(pFormatCtx_)
    {
        avformat_free_context(pFormatCtx_);
    }
}

void AVDeMuxer::FetchStream(const QString path)
{
     //获取流信息
    bool ret =true;
    if(streamCb_)
    {
        ret=FetchStreamInfo(path);
        streamCb_(ret);
    }
    if(!ret)
    {
        return;
    }

    AVPacketPtr packet = nullptr;
    while(!quit_ && pFormatCtx_){
        packet =AVPacketPtr(av_packet_alloc(),[](AVPacket* p){av_packet_free(&p);});
        //开始读取数据
        int re = av_read_frame(pFormatCtx_,packet.get());
        if(re ==0)
        {
            if(packet->stream_index == videoIndex)
            {
                //视频包数据
                //开始解码音视频数据包
                qDebug() <<"视频包";
            }
            else if(packet->stream_index == AudioIndex)
            {
               //音频数据包
                qDebug() <<"音频包";
            }
        }
        else
        {
            av_packet_unref(packet.get());
            break;
        }
    }
}

bool AVDeMuxer::FetchStreamInfo(const QString path)
{
     //获取流信息
    if(avformat_open_input(&pFormatCtx_,path.toStdString().c_str(),nullptr,nullptr) != 0)
     {
         qDebug() <<"avformat_open_input failed";
         return false;
     }

    if(avformat_find_stream_info(pFormatCtx_,nullptr) < 0)
     {
        qDebug() <<"avformat_find_stream_info failed";
        return false;
     }
for(int i=0;i<pFormatCtx_->nb_streams;i++)
     {
         if(pFormatCtx_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
        {

            videoIndex = i;
        }
         else if(pFormatCtx_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
         {
             AudioIndex =i;
         }
        else
        {
            continue;
        }
    }
    if(videoIndex == -1)
    {
         qDebug()<<"含有视频流";
    }
    if(AudioIndex == -1)
    {
        qDebug()<<"含有音频流";
    }
    return true;
}

int AVDeMuxer::InterruptFountion(void *arg)
{
    AVDeMuxer* thiz = (AVDeMuxer*)arg;
    return thiz->quit_; //0 运行 1 停止
}
